package etc

import (
	"encoding/json"
	"errors"
	"fmt"

	"io/ioutil"
	"log"
	"net"
	"os"
)

//配置文件部分

type Storage struct {
	GroupPath string `json:"group_path"`
	LogPath   string `json:"log_path"`
}

type Tracker struct {
	Port  int    `json:"port"`
	Host  string `json:"host"`
	Token string `json:"token_pwd"` //加密令牌
	Web   string `json:"web"`       //静态文件目录
}

type Conf struct { //配置文件部分
	Storage *Storage `json:"storage"`
	Tracker *Tracker `json:"tracker"`
}

//读取配置文件，生成Conf对象
func LoadConfig(path string) *Conf {
	buf, err := ioutil.ReadFile(path) //读取文件IO
	if err != nil {
		log.Panic("LoadConfig err", err)
	}

	//read buf
	conf := &Conf{
		Storage: new(Storage),
		Tracker: new(Tracker),
	}
	err = json.Unmarshal(buf, conf)
	if err != nil {
		panic(err)
	}

	return conf

}

//获取Storage的配置文件
func (c *Conf) GetStorage() *Storage {
	return c.Storage
}

//获取Tracker配置文件
func (c *Conf) GetTracker() *Tracker {
	return c.Tracker
}

const (
	StorageConfErr = "errCode: %d || The %s in the storage configuration file is in error %s"

	TrackerConfErr = "errCode: %d || The %s in the tracker configuration file is in error %s"
)

//校验配置文件, etc中，不要写入日志
func VerifyStorage(storage *Storage) error {
	_, err := os.Stat(storage.GroupPath)
	if err != nil {
		return errors.New(fmt.Sprintf(StorageConfErr, 0, "group_path", err.Error()))
	}

	_, err = os.Stat(storage.LogPath)
	if err != nil {
		return errors.New(fmt.Sprintf(StorageConfErr, 0, "log_path", err.Error()))
	}

	return nil

}

func VerifyTracker(tracker *Tracker) error {
	address := net.ParseIP(tracker.Host)
	if address == nil {
		return errors.New(fmt.Sprintf(TrackerConfErr, 0, "host", "host err"))
	}

	if !(tracker.Port < 65535 && tracker.Port > 0) {
		return errors.New(fmt.Sprintf(TrackerConfErr, 0, "port", "host err"))
	}

	if len(tracker.Token) != 16 {
		return errors.New(fmt.Sprintf(TrackerConfErr, 0, "token", "The length of the token must be 16"))
	}

	if tracker.Web != "" {
		_, err := os.Stat(tracker.Web)
		if err != nil {
			return errors.New(fmt.Sprintf(TrackerConfErr, 0, "web", err.Error()))

		}
	}

	return nil
}
